package com.eedi.framework.oauth2.convert;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.eedi.framework.common.core.KeyValue;
import com.eedi.framework.common.enums.UserTypeEnum;
import com.eedi.framework.common.util.collection.CollectionUtils;
import com.eedi.framework.common.util.object.BeanUtils;
import com.eedi.framework.oauth2.controller.org.vo.open.OrgOAuth2OpenAccessTokenRespVO;
import com.eedi.framework.oauth2.controller.org.vo.open.OrgOAuth2OpenAuthorizeInfoRespVO;
import com.eedi.framework.oauth2.controller.org.vo.open.OrgOAuth2OpenCheckTokenRespVO;
import com.eedi.framework.oauth2.dal.dataobject.OrgOAuth2AccessTokenDO;
import com.eedi.framework.oauth2.util.OrgOAuth2Utils;
import com.eedi.framework.security.core.util.SecurityFrameworkUtils;
import com.eedi.framework.oauth2.dal.dataobject.OrgOAuth2ApproveDO;
import com.eedi.framework.oauth2.dal.dataobject.OrgOAuth2ClientDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Mapper
public interface OrgOAuth2OpenConvert {

    OrgOAuth2OpenConvert INSTANCE = Mappers.getMapper(OrgOAuth2OpenConvert.class);

    default OrgOAuth2OpenAccessTokenRespVO convert(OrgOAuth2AccessTokenDO bean) {
        OrgOAuth2OpenAccessTokenRespVO respVO = BeanUtils.toBean(bean, OrgOAuth2OpenAccessTokenRespVO.class);
        respVO.setTokenType(SecurityFrameworkUtils.AUTHORIZATION_BEARER.toLowerCase());
        respVO.setExpiresIn(OrgOAuth2Utils.getExpiresIn(bean.getExpiresTime()));
        respVO.setScope(OrgOAuth2Utils.buildScopeStr(bean.getScopes()));
        return respVO;
    }

    default OrgOAuth2OpenCheckTokenRespVO convert2(OrgOAuth2AccessTokenDO bean) {
        OrgOAuth2OpenCheckTokenRespVO respVO = BeanUtils.toBean(bean, OrgOAuth2OpenCheckTokenRespVO.class);
        respVO.setExp(LocalDateTimeUtil.toEpochMilli(bean.getExpiresTime()) / 1000L);
        respVO.setUserType(UserTypeEnum.MEMBER_SYS.getCode());
        return respVO;
    }

    default OrgOAuth2OpenAuthorizeInfoRespVO convert(OrgOAuth2ClientDO client, List<OrgOAuth2ApproveDO> approves) {
        // 构建 scopes
        List<KeyValue<String, Boolean>> scopes = new ArrayList<>(client.getScopes().size());
        Map<String, OrgOAuth2ApproveDO> approveMap = CollectionUtils.convertMap(approves, OrgOAuth2ApproveDO::getScope);
        client.getScopes().forEach(scope -> {
            OrgOAuth2ApproveDO approve = approveMap.get(scope);
            scopes.add(new KeyValue<>(scope, approve != null ? approve.getApproved() : false));
        });
        // 拼接返回
        return new OrgOAuth2OpenAuthorizeInfoRespVO(
                new OrgOAuth2OpenAuthorizeInfoRespVO.Client(client.getName(), client.getLogo()), scopes);
    }

}
